home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / uae / uae-0.4.3 / mac.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  13KB  |  562 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * Mac port specific stuff
  5.   * 
  6.   * (c) 1996 Ernesto Corvi
  7.   */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <QDOffscreen.h>
  13. #include <Palettes.h>
  14. #include <Profiler.h>
  15.  
  16. #include "mackbd.h"
  17. #include "config.h"
  18. #include "amiga.h"
  19. #include "options.h"
  20. #include "memory.h"
  21. #include "custom.h"
  22. #include "newcpu.h"
  23. #include "xwin.h"
  24. #include "keyboard.h"
  25. #include "keybuf.h"
  26.  
  27. extern bool left, right, top, bot, but;
  28.  
  29. KeyMap keys,keysold;
  30. static int screen;
  31. Boolean    RM=false,Joy=false;
  32. WindowPtr mywin;
  33. short    gOldMBarHeight;
  34. RgnHandle gMBarRgn;
  35. static int bitdepth;
  36. KeyMap theKeys;
  37.  
  38. unsigned long refresh;
  39. char *xlinebuffer;
  40. unsigned int *obuff;
  41. long int xcolors[4096];
  42.  
  43.  /* Keyboard and mouse */
  44.  
  45. static bool keystate[256];
  46.  
  47. bool buttonstate[3];
  48. int lastmx, lastmy;
  49. bool newmousecounters;
  50. static bool inwindow;
  51.  
  52. int GetRawCode (long set0, long set1, long set2, long set3);
  53.  
  54. static inline unsigned long doMask(int p, int bits, int shift)
  55. {
  56.     /* p is a value from 0 to 15 (Amiga color value)
  57.      * scale to 0..255, shift to align msb with mask, and apply mask */
  58.  
  59.     unsigned long val = p * 0x11111111UL;
  60.     val >>= (32 - bits);
  61.     val <<= shift;
  62.  
  63.     return val;
  64. }
  65.  
  66. static void InitXColors(void)
  67. {
  68.     int n=16;
  69.     int red_bits = 5;
  70.     int green_bits = 5;
  71.     int blue_bits = 5;
  72.     int red_shift = 10;
  73.     int green_shift = 5;
  74.     int blue_shift = 0;
  75.     int i=0;
  76.     int r,g,b;
  77.     
  78.     for(i = 0; i < 4096; i++) {
  79.     r = i >> 8;
  80.     g = (i >> 4) & 0xF;
  81.     b = i & 0xF;
  82.     xcolors[i] = (doMask(r, red_bits, red_shift) 
  83.               | doMask(g, green_bits, green_shift) 
  84.               | doMask(b, blue_bits, blue_shift));
  85.     }
  86. }
  87.  
  88. static void InitToolbox(void)
  89. {
  90.     InitGraf (&qd.thePort);
  91.     InitFonts ();
  92.     FlushEvents (everyEvent,0);
  93.     InitWindows ();
  94.     InitMenus ();
  95.     TEInit ();
  96.     InitDialogs (nil);
  97.     InitCursor ();
  98. }
  99.  
  100. static void HideMenuBar(void)
  101. {
  102.     Rect mBarRect;
  103.  
  104.     /* GET RID OF THE MENU BAR */
  105.                     
  106.     gOldMBarHeight = GetMBarHeight();
  107.     /* make the Menu Bar's height zero */
  108.     LMSetMBarHeight(0);
  109.     SetRect(&mBarRect, qd.screenBits.bounds.left, qd.screenBits.bounds.top,
  110.         qd.screenBits.bounds.right, qd.screenBits.bounds.top + gOldMBarHeight);
  111.     gMBarRgn = NewRgn();
  112.     RectRgn(gMBarRgn, &mBarRect);
  113.     UnionRgn(LMGetGrayRgn(), gMBarRgn, LMGetGrayRgn());    /* tell the desktop it covers the menu bar */
  114.  
  115.     PaintOne(nil, gMBarRgn); /* redraw desktop */
  116. }
  117.  
  118. static void ShowMenuBar(void)
  119. {
  120.     LMSetMBarHeight(gOldMBarHeight); /* make the menu bar's height normal */
  121.     DiffRgn(LMGetGrayRgn(), gMBarRgn, LMGetGrayRgn()); /* remove the menu bar from the desktop */
  122.     DisposeRgn(gMBarRgn);
  123. }
  124.  
  125. int graphics_init()
  126. {
  127.     int i;
  128.     long p1;
  129.     long tmp;
  130.  
  131. #ifdef DEFAULT_WANT_ASPECT
  132.     Rect    windowRectangle={0,0,480,640};
  133. #else
  134.     Rect    windowRectangle={0,0,240,320};
  135. #endif
  136.     InitToolbox();
  137.     
  138.     HideMenuBar();
  139.     mywin = NewCWindow(nil, &windowRectangle, "\pUAE", true, 2, (WindowPtr)-1L, false, 0);
  140.     SetPort(mywin);
  141.  
  142.     PaintRect(&qd.screenBits.bounds);
  143.     
  144.     xlinebuffer = (char *)malloc (3200);
  145.     InitXColors();
  146.     buttonstate[0] = buttonstate[1] = buttonstate[2] = false;
  147.     for(i=0; i<256; i++) keystate[i] = false;
  148.     
  149.     lastmx = lastmy = 0; newmousecounters = false; inwindow = false;
  150.     
  151.     obuff=(unsigned int *)NewPtrClear(481*1280);
  152.  
  153.     for(p1=0;p1 < (480*1280);p1++)
  154.     *obuff=-1;
  155.     
  156.     HideCursor();
  157.     refresh=TickCount();
  158.     
  159. /*    tmp=ProfilerInit(collectDetailed,bestTimeBase,200,10); */
  160.     return 1;
  161. }
  162.  
  163. void graphics_leave()
  164. {
  165. /*    ProfilerDump((unsigned char *)"\pmyProf");
  166.     ProfilerTerm();
  167.  */
  168.     DisposeWindow(mywin);
  169.     ShowCursor();
  170.     ShowMenuBar();
  171.     FlushEvents (everyEvent,0);
  172.     ExitToShell();
  173. }
  174.  
  175. static bool next_line_double;
  176. static int next_line_pos = 0;
  177.  
  178. void flush_screen ()
  179. {  
  180.     GrafPtr oldPort;
  181.     short    y,x,daColor=0;
  182.     RGBColor    daColorRGB;
  183.     unsigned char *winbaseaddr;
  184.     double *src,*dest;
  185.     unsigned long winrowbytes;
  186.     PixMapHandle    ph;
  187.     
  188.     if (TickCount() < refresh + 4) return;
  189.     GetPort(&oldPort);
  190.     SetPort(mywin);
  191.    
  192.     ph=GetGWorldPixMap((CGrafPort *) mywin);
  193.     LockPixels(ph);
  194.     winbaseaddr=( unsigned char *) GetPixBaseAddr(ph);
  195.     winrowbytes=(*ph)->rowBytes & 0x3FFF;
  196.     winbaseaddr-=((**ph).bounds.left);
  197.     winbaseaddr-=((**ph).bounds.top*winrowbytes);
  198.     dest=(double *)winbaseaddr;
  199.     src=(double *)obuff;
  200.    
  201. #ifdef DEFAULT_WANT_ASPECT
  202.     for (y=1; y< 480; y++)
  203. #else
  204.     for (y=1; y< 239; y++)
  205. #endif
  206.     {    
  207. #ifdef DEFAULT_WANT_ASPECT
  208.     for (x=0;x < 160;x++)
  209. #else
  210.     for (x=0;x < 80;x++)
  211. #endif
  212.     {  
  213.         *dest++ = *src++;
  214.     }
  215.     dest=(double *)(winbaseaddr+(y*winrowbytes));
  216. #ifndef DEFAULT_WANT_ASPECT
  217.     src += 640;
  218. #endif
  219.     }
  220.     UnlockPixels(ph);
  221.     SetPort(oldPort);
  222.  
  223. }
  224.  
  225. void prepare_line (int y, bool need_double)
  226. {
  227.     next_line_double = need_double;
  228.     next_line_pos = y;
  229. }
  230.  
  231. void flush_line()
  232. {
  233.     short i;
  234.     char *dst,*src;
  235.     double *dst1,*src1;
  236.      
  237.     if ((next_line_pos < 508) && (next_line_pos > 28))
  238.     {    
  239.     dst=(char *)obuff+((next_line_pos-28)*1280);
  240.     src=(char *)xlinebuffer+292;
  241. #ifdef DEFAULT_WANT_ASPECT
  242.     BlockMove(src,dst,1280);
  243. #else
  244.     BlockMove(src,dst,640);
  245. #endif        
  246.     }
  247.     if (next_line_double)
  248.     {    
  249.     if ((next_line_pos+1 < 508) && (next_line_pos+1 > 28))
  250.     {    
  251.         dst1=(double *)obuff+((next_line_pos+1-28)*160);
  252.         src1=(double *)obuff+((next_line_pos-28)*160);
  253.         for (i=0;i < 160;i++)
  254.         {  
  255.         *dst1++=*src1++;
  256.         }
  257.     }
  258.     }
  259. }
  260.  
  261. /* Decode KeySyms. This function knows about all keys that are common 
  262.  * between different keyboard languages.
  263.  */
  264. static int kc_decode (long ks)
  265. {    
  266.     switch (ks)
  267.     {
  268.      case kAKeyMap: return AK_A;
  269.      case kBKeyMap: return AK_B;
  270.      case kCKeyMap: return AK_C;
  271.      case kDKeyMap: return AK_D;
  272.      case kEKeyMap: return AK_E;
  273.      case kFKeyMap: return AK_F;
  274.      case kGKeyMap: return AK_G;
  275.      case kHKeyMap: return AK_H;
  276.      case kIKeyMap: return AK_I;
  277.      case kJKeyMap: return AK_J;
  278.      case kKKeyMap: return AK_K;
  279.      case kLKeyMap: return AK_L;
  280.      case kMKeyMap: return AK_M;
  281.      case kNKeyMap: return AK_N;
  282.      case kOKeyMap: return AK_O;
  283.      case kPKeyMap: return AK_P;
  284.      case kQKeyMap: return AK_Q;
  285.      case kRKeyMap: return AK_R;
  286.      case kSKeyMap: return AK_S;
  287.      case kTKeyMap: return AK_T;
  288.      case kUKeyMap: return AK_U;
  289.      case kVKeyMap: return AK_V;
  290.      case kWKeyMap: return AK_W;
  291.      case kXKeyMap: return AK_X;
  292.      
  293.      case k0KeyMap: return AK_0;
  294.      case k1KeyMap: return AK_1;
  295.      case k2KeyMap: return AK_2;
  296.      case k3KeyMap: return AK_3;
  297.      case k4KeyMap: return AK_4;
  298.      case k5KeyMap: return AK_5;
  299.      case k6KeyMap: return AK_6;
  300.      case k7KeyMap: return AK_7;
  301.      case k8KeyMap: return AK_8;
  302.      case k9KeyMap: return AK_9;
  303.      
  304.      case kKP0KeyMap: return AK_NP0;
  305.      case kKP1KeyMap: return AK_NP1;
  306.      case kKP2KeyMap: return AK_NP2;
  307.      case kKP3KeyMap: return AK_NP3;
  308.      case kKP4KeyMap: return AK_NP4;
  309.      case kKP5KeyMap: return AK_NP5;
  310.      case kKP6KeyMap: return AK_NP6;
  311.      case kKP7KeyMap: return AK_NP7;
  312.      case kKP8KeyMap: return AK_NP8;
  313.      case kKP9KeyMap: return AK_NP9;
  314.     
  315.      case kF1KeyMap: return AK_F1;
  316.      case kF2KeyMap: return AK_F2;
  317.      case kF3KeyMap: return AK_F3;
  318.      case kF4KeyMap: return AK_F4;
  319.      case kF5KeyMap: return AK_F5;
  320.      case kF6KeyMap: return AK_F6;
  321.      case kF7KeyMap: return AK_F7;
  322.      case kF8KeyMap: return AK_F8;
  323.      case kF9KeyMap: return AK_F9;
  324.      case kF10KeyMap: return AK_F10;
  325.     
  326.      case kBackSpaceKeyMap: return AK_BS;
  327.      case kTabKeyMap: return AK_TAB;
  328.      case kReturnKeyMap: return AK_RET;
  329.      case kEscapeKeyMap: return AK_ESC;
  330.      
  331.      case kSpaceBarMap: if (Joy) return -1; else return AK_SPC;
  332.      
  333.      case kUpArrowKeyMap: if (Joy) return -1; else return AK_UP;
  334.      case kDownArrowKeyMap: if (Joy) return -1; else return AK_DN;
  335.      case kLeftArrowKeyMap: if (Joy) return -1; else return AK_LF;
  336.      case kRightArrowKeyMap: if (Joy) return -1; else return AK_RT;
  337.     
  338.      case kF11KeyMap: graphics_leave();
  339.  
  340. /*     case kF12KeyMap: return AK_mousestuff;*/
  341.      case kF12KeyMap: { Joy=!Joy; SysBeep(0); return -1; }
  342.  
  343.      case kPgUpKeyMap: return AK_RAMI;
  344.      case kPgDnKeyMap: return AK_LAMI;
  345.      case kBackSlash: return AK_BACKSLASH;
  346.     }
  347.     return -1;
  348. }
  349.  
  350. static int decode_us(long ks)
  351. {
  352.     switch(ks) {
  353.     /* US specific */
  354.  
  355.      case kYKeyMap: return AK_Y;
  356.      case kZKeyMap: return AK_Z;
  357.      case kLBracketKeyMap: return AK_LBRACKET;
  358.      case kRBracketKeyMap: return AK_RBRACKET;
  359.      case kCommaKeyMap: return AK_COMMA;
  360.      case kPeriodKeyMap: return AK_PERIOD;
  361.      case kSlashKeyMap: return AK_SLASH;
  362.      case kSemiColonKeyMap: return AK_SEMICOLON;
  363.      case kMinusKeyMap: return AK_MINUS;
  364.      case kEqualKeyMap: return AK_EQUAL;
  365.      case kQuoteKeyMap: return AK_QUOTE;
  366.     }
  367.  
  368.     return -1;
  369. }
  370.  
  371. static int decode_de(long ks)
  372. {
  373.     switch(ks) {
  374. /* DE specific
  375.      case XK_Y: case XK_y: return AK_Z;
  376.      case XK_Z: case XK_z: return AK_Y;
  377.      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
  378.      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
  379.      case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
  380.      case XK_plus: case XK_asterisk: return AK_RBRACKET;
  381.      case XK_comma: return AK_COMMA;
  382.      case XK_period: return AK_PERIOD;
  383.      case XK_less: case XK_greater: return AK_LTGT;
  384.      case XK_numbersign: return AK_NUMBERSIGN;
  385.      case XK_ssharp: return AK_MINUS;
  386.      case XK_apostrophe: return AK_EQUAL;
  387.      case XK_asciicircum: return AK_00;
  388.      case XK_minus: return AK_SLASH;        
  389. */
  390.     }
  391.  
  392.     return -1;
  393. }
  394.  
  395. static int keycode2amiga(long code)
  396. {
  397.     long ks;
  398.     int as;
  399.     
  400.     ks = (code & keyCodeMask) >> 8;
  401.     as = kc_decode (ks);
  402.     
  403.     if (as == -1) {        
  404.     switch(keyboard_lang) {
  405.      case KBD_LANG_US:
  406.         as = decode_us(ks);
  407.         break;
  408.         
  409.      case KBD_LANG_DE:
  410.         as = decode_de(ks);
  411.         break;
  412.         
  413.      default:
  414.         as = -1;
  415.         break;
  416.     }
  417.     }
  418.     if(-1 != as)
  419.     return as;
  420.     return -1;
  421. }
  422.  
  423. void handle_events()
  424. {
  425.     Boolean repeat;
  426.     Boolean itHappened;
  427.     Point   mpos;
  428.     EventRecord event;
  429.     int kc,i,count;
  430.     
  431.     SetEventMask(-1);
  432.     SelectWindow(mywin);
  433.     HideCursor();
  434.     
  435.     GetKeys(keys);
  436.     if (BitTst(&keys, kCommandRawKey))
  437.     RM=true;
  438.     else
  439.     RM=false;
  440.     
  441.     if (BitTst(&keys, kShiftRawKey))
  442.     {    
  443.     if (!keystate[AK_LSH]) {
  444.         keystate[AK_LSH] = true;
  445.         record_key (AK_LSH << 1);
  446.         goto label1;
  447.     }
  448.     } else {
  449.     if (keystate[AK_LSH]) {
  450.         keystate[AK_LSH] = false;
  451.         record_key ((AK_LSH << 1) | 1);
  452.         goto label1;
  453.     }
  454.     }
  455.     if (BitTst(&keys, kControlRawKey))
  456.     {    
  457.     if (!keystate[AK_CTRL]) {
  458.         keystate[AK_CTRL] = true;
  459.         record_key (AK_CTRL << 1);
  460.         goto label1;
  461.     }
  462.     } else {    
  463.     if (keystate[AK_CTRL]) {
  464.         keystate[AK_CTRL] = false;
  465.         record_key ((AK_CTRL << 1) | 1);
  466.         goto label1;
  467.     }
  468.     }
  469.     if (BitTst(&keys, kOptionRawKey))
  470.     {    
  471.     if (!keystate[AK_LALT]) {
  472.         keystate[AK_LALT] = true;
  473.         record_key (AK_LALT << 1);
  474.         goto label1;
  475.     }
  476.     } else {
  477.     if (keystate[AK_LALT]) {
  478.         keystate[AK_LALT] = false;
  479.         record_key ((AK_LALT << 1) | 1);
  480.         goto label1;
  481.     }
  482.     }
  483.     do {
  484.     repeat = false;
  485.     newmousecounters = false;
  486.     itHappened=WaitNextEvent(-1,&event,0L,0L);
  487.  
  488.     switch(event.what) {
  489.      case keyDown:
  490.      case autoKey: {    
  491.          int kc = keycode2amiga(event.message);
  492.          if (kc == -1) break;
  493.          switch (kc) {
  494.           case AK_mousestuff:
  495. #if 0
  496.              if (keystate[AK_CTRL])
  497.              mousesetup();
  498.               else 
  499. #endif
  500.              togglemouse();
  501.               break;
  502.  
  503.           case AK_inhibit:
  504.               inhibit_frame ^= 1;
  505.               break;
  506.  
  507.           default:
  508.               if (!keystate[kc]) {
  509.              keystate[kc] = true;
  510.              record_key (kc << 1);
  511.          }
  512.          break;
  513.          }
  514.          break;
  515.      }
  516.      case keyUp: {         
  517.          if (Joy) break;
  518.          kc = keycode2amiga(event.message);
  519.          if (kc == -1) break;
  520.          keystate[kc] = false;
  521.          record_key ((kc << 1) | 1);
  522.          break;
  523.      }
  524.      case mouseDown:
  525.         if (RM == true) buttonstate[2] = true;
  526.         else buttonstate[0] = true;
  527.         break;
  528.      case mouseUp:
  529.         buttonstate[0] = false;
  530.         buttonstate[2] = false;
  531.         break;
  532.     }
  533.     GetMouse(&mpos);
  534.     if (mpos.h != lastmx) { lastmx=mpos.h; repeat = true; }
  535.     if (mpos.v != lastmy) { lastmy=mpos.v; repeat = true; }
  536.     } while (repeat);
  537.     
  538. label1:
  539.     /* "Affengriff" */
  540.     if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
  541.         MC68000_reset();
  542. }
  543.  
  544. bool debuggable()
  545. {
  546.     return true;
  547. }
  548.  
  549. bool needmousehack()
  550. {
  551.     return true;
  552. }
  553.  
  554. void LED(int on)
  555. {
  556. }
  557.  
  558. void parse_cmdline ()
  559. {
  560.     /* No commandline on the Mac. */
  561. }
  562.